/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 * \file
 * \brief Module handling properties of a single connection entry (Implementation)
 * \author Antti Maula <antti.maula@tkk.fi>
 */

//*****************************************************************************
//*****************************************************************************
#include "owndebug.h"
#include "connectionListEntry.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>

//*****************************************************************************
//*****************************************************************************

TConnectionListEntry *connectionListEntryCreate( unsigned int ID,
                                                 EConnectionType type,
                                                 EConnectionState state,
                                                 EConnectionProtocol protocol,
						 EConnectionEntryFlags flags,
						 TConnection *connection )
{
  // Instantiate new entry
  TConnectionListEntry *newEntry = (TConnectionListEntry *)malloc(sizeof(TConnectionListEntry));
  assert(newEntry != NULL);
  
  // Init!
  connectionListEntryInit(newEntry, ID, type, state, protocol, flags, connection);

  // Return the new entry
  return newEntry;
}
//*****************************************************************************

void connectionListEntryInit( TConnectionListEntry *e, 
			      unsigned int ID,
                              EConnectionType type,
                              EConnectionState state,
                              EConnectionProtocol protocol,
			      EConnectionEntryFlags flags,
			      TConnection *connection )
{
  // Trivial checks
  assert(e != NULL);

  // Clear
  memset(e, 0x00, sizeof(TConnectionListEntry));

  // Assign parameters
  e->connectionID = ID;
  e->connection = connection;
  e->flags = flags;
  e->state = state;
  e->type = type;
  e->protocol = protocol;
  
  // Initialize the per-connection buffers
  bufferInit(&e->inputBuffer);  
  bufferInit(&e->outputBuffer);
  bufferSetMinimumIncrement(&e->inputBuffer, 100000);
  bufferSetMinimumIncrement(&e->outputBuffer, 100000);
  // Is initialized
  e->initialized = 1;
 
  dPrint(4,"Initialized new entry %p", e);
 
  // Return
  return;
}
//*****************************************************************************

void connectionListEntryDeinit( TConnectionListEntry *e )
{
  assert(e != NULL);
  assert(e->initialized == 1);

  // Clean up connection
  if (e->connection != NULL) {
    connectionDisconnect(e->connection);
    connectionDeinit(e->connection);
    free(e->connection);
  }
  
  // Clean up buffer
  bufferDeinit(&e->inputBuffer);
  bufferDeinit(&e->outputBuffer);

  dPrint(4,"Deinitialized entry %p", e);

  // Mark destroyed
  e->initialized = 0;
}
//*****************************************************************************

void connectionListEntryCreateAutoReconnectCtrl( TConnectionListEntry *e, 
                                                 unsigned reconnect_min_interval_ms )
{
  if (! e->autoReconnectCtrlPtr) {
    // Allocate memory for structure
    e->autoReconnectCtrlPtr = (TAutoReconnectCtrl *)malloc(sizeof(TAutoReconnectCtrl));

    // Clear
    memset(e->autoReconnectCtrlPtr, 0x00, sizeof(TAutoReconnectCtrl));

    // Store available parameters.
    e->autoReconnectCtrlPtr->reconnect_min_interval = reconnect_min_interval_ms;

  } else {
    dPrint(ODERROR,"ERROR: Attempted to create AutoReconnectCtrl even one exists!");

  }
}
//*****************************************************************************

void connectionListEntryDestroyAutoReconnectCtrl( TConnectionListEntry *e )
{
  if ( e->autoReconnectCtrlPtr ) {
    free(e->autoReconnectCtrlPtr);
    e->autoReconnectCtrlPtr = NULL;

  } else {
    dPrint(ODERROR,"ERROR: Attempted to delete AutoReconnectCtrl even one doesn't exists!");

  }
}
//*****************************************************************************

void connectionListEntryDestroy( TConnectionListEntry *e )
{
  assert(e != NULL);

  // Clean up inside
  connectionListEntryDeinit(e);

  // Remove allocated memory
  free(e);
  
  // return
  return;
}
//*****************************************************************************

void connectionListEntryDump( int l, const TConnectionListEntry *e )
{
  dPrint(l, 
	  "connectionListEntry:\n"
	  "\tID:\t0x%08x\r\n"
	  "\ti-len:\t%d\r\n"
	  "\to-len:\t%d\r\n"
	  "\tflags:\t0x%02x\r\n"
	  "\tconn:\t0x%p",
	  e->connectionID,
	  bufferGetLength(&e->inputBuffer),
	  bufferGetLength(&e->outputBuffer),
	  e->flags,
	  e->connection);
	  
}
//*****************************************************************************
//*****************************************************************************
